今天要來介紹的是狀態管理,透過狀態管理可以使每個元件都能夠取得一致的狀態,也能透過此方式來進行參數傳遞,加上之前介紹的元件傳值技巧,魔術技巧 - 父子溝通問題與魔術技巧 - 傳值技巧,這就是目前 Blazor WebAssembly 元件傳值的三種技巧。
還記得相依性注入魔術技巧內容吧?我們可以放任意服務實體進 DI Container 中,而以 Singleton
為生命週期的服務,可以確保每個需要此服務的元件都得到相同實體,所以我們也可以將資料模型當成服務注入,來進行元件間的傳值。
首先建立一個資料模型:
// Day23SampleModel.cs
public class Day23SampleModel
{
public string Value { get; set; }
}
然後將該服務新增到 DI:
// Program.cs
builder.Services.AddSingleton<Day23SampleModel>();
如此一來我們就可以使用 @inject Day23SampleModel Day23SampleModel
來從 di container 中取得同一個 Day23SampleModel
實體如:
@* Day23Sample.razor *@
@inject Day23SampleModel Day23SampleModel
<p>
Day23SampleModel.Value: @Day23SampleModel.Value
</p>
<input @bind="Day23SampleModel.Value" />
@* Day23Sample2.razor *@
@inject Day23SampleModel Day23SampleModel
<p>
Day23SampleModel.Value: @Day23SampleModel.Value
</p>
<input @bind="Day23SampleModel.Value" />
當任何一個元件修改了 Day23SampleModel.Value
的值,另一個元件也會被修改。
以上就是 .NET 元件狀態管理也是傳值的第三種方式。
但此種狀態管理方式是寫在記憶體中,若想要保留在瀏覽器上,則可以考慮使用 JavaScript 來操作 localStorage
和 sessionStorage
集合:
localStorage
:範圍設定為瀏覽器的視窗,如果使用者重載或關閉頁面甚至重新開啟瀏覽器,狀態都會持續存在,且當使用者開啟多個瀏覽器索引標籤,會在索引標籤之間共用狀態,直到明確清除為止,資料會持續存在。
sessionStorage
:範圍設定為瀏覽器索引標籤,如果使用者重載此索引標籤,狀態會持續存在,直到使用者關閉索引標籤或瀏覽器,狀態就會遺失,而且如果使用者開啟多個瀏覽器索引標籤,每個索引標籤都有自己獨立的資料版本。
以 localStorage
來做練習,我們可以撰寫一個 JavaScript 方法如:
window.exampleJsFunctions = {
setLocalStorageItem: function (key, value) {
localStorage.setItem(key, value);
},
getLocalStorageItem: function (key) {
return localStorage.getItem(key);
}
};
並在初始化時,從 localStorage
取得對應的值,並提供儲存按鈕來更新 localStorage
的內容:
<p>
LocalStorage: @localStorageValue
</p>
<input @bind="localStorageValue" />
<button @onclick="Save">Save</button>
@code {
private string localStorageValue;
protected override async Task OnInitializedAsync()
{
localStorageValue = await GetLocalStorageItem("test");
await base.OnInitializedAsync();
}
public async Task Save()
{
await SetLocalStorageItem("test", this.localStorageValue);
}
public async Task SetLocalStorageItem(string key, string value)
{
await JSRuntime.InvokeVoidAsync("exampleJsFunctions.setLocalStorageItem", key, value);
}
public async Task<string> GetLocalStorageItem(string key)
{
return await JSRuntime.InvokeAsync<string>("exampleJsFunctions.getLocalStorageItem", key);
}
}
當然也可以將存取 localStorage
的方法抽成服務,這樣以後有元件需要使用 localStorage
就可以直接注入服務啦。
以上就是狀態管理的方法,若想要參考完整程式碼可以到範本程式碼 - day23看看唷。
感謝大家的閱讀,我們明天見。